#include "Event.h"

std::map<std::string, Event*> Event::events;
Event* Event::dummy = 0;
/*********************************************************/
std::string Event::getName()
{
	return( name );
}
/*********************************************************/
void Event::wait()
{
	sem->wait();
	mutex.lock();
	semValue--;
	if ( count > 0 ) {
		sem->set();
		count--;
		semValue++;
	}
	mutex.unlock();
}
/*********************************************************/
bool Event::tryWait(long milliseconds)
{
	if ( sem->tryWait(milliseconds) ) {
		mutex.lock();
		semValue--;
		if ( count > 0 ) {
			semValue++;
			count--;
			sem->set();
		}
		mutex.unlock();
		return( true );
	} else {
		return( false );
	}
	return( false );
}
/*********************************************************/
void Event::set()
{
	mutex.lock();
	if ( semValue < SEM_MAX ) {
		semValue++;
		sem->set();
	} else {
		count++;
	}
	mutex.unlock();
}
/*********************************************************/
void Event::reset()
{
	mutex.lock();
	while ( semValue > 0 ) {
		sem->wait();
		semValue--;
	}
	count = 0;
	mutex.unlock();
}
/*********************************************************/
Event::Event()
{
	sem = new( Poco::Semaphore )(0,SEM_MAX);
	count = 0;
	semValue = 0;
}
/*********************************************************/
Event::~Event()
{
	if ( this == dummy ) {
		std::map<std::string, Event*>::iterator it;
		for ( it = events.begin(); it != events.end(); it++ )
		{
			std::string name = it->first;
			Event* 	    event = it->second;
			delete(event->sem);
			delete(event);
		}
		delete(sem);
	}
}
/*********************************************************/
Event* Event::Instance(const std::string& name)
{
	// Check if we allready have the dummy event
	static Event dummy;
	Event::dummy = &dummy;

	// Search for an existing event
	std::map<std::string, Event*>::iterator it;
	it = events.find(name);
	if ( it == events.end() ) {
		Event* ev = new( Event );
		ev->name = name;
		events.insert(std::pair<std::string, Event*>(name, ev));
		return( ev );
	} else {
		return( (*it).second );
	}
}
